/* Copyright Andy Mitchell 2007. No warranties */

function GTDInboxPage(gtdinboxBrowser, doc){
try{

	this.id = (new Date()).valueOf();
	this.gtdinboxBrowser = gtdinboxBrowser;
	this.db = gtdinboxBrowser.db;
	this.sp = new StoredProceduresGTD(this);
	this.stringBundle = gtdinboxBrowser.stringBundle;
	this.eventObservers = new EventObservers(this);
	
	this.doc = doc;
	this.mainDoc = doc; 
	this.window = doc.defaultView;
	this.unsafeWindow = this.window.wrappedJSObject;
	this.attachToBrowser();
	
		
	this._gtdFrame = this.doc.location.href.match(/gtd\=(\d+)/i);
	if( this._gtdFrame ) this._gtdFrame = this._gtdFrame[1];	// a unique id	
	
	
	/*
	var window = pageDoc.defaultView;
	var unsafeWindow = window.wrappedJSObject;
	if( window && unsafeWindow ){
		window.addEventListener('load', function() {
		if (unsafeWindow.gmonkey) {
			unsafeWindow.gmonkey.load('1', function(gmail) {
			function setViewType() {
				var str = '';
				switch (gmail.getActiveViewType()) {
				case 'tl': str = 'Threadlist'; break;
				case 'cv': str = 'Conversation'; break;
				case 'co': str = 'Compose'; break;
				case 'ct': str = 'Contacts'; break;
				case 's': str = 'Settings'; break;
				default: str = 'Unknown';
				}
				module.setContent(str);
			}
			var module = gmail.addNavModule('View Monitor');
			gmail.registerViewChangeCallback(setViewType);
			setViewType();
			});
		}
		}, true);
	}
	*/
	
	var onLoad = GIPROTOTYPE.bind( this, function() {
		try{
			if( this.unsafeWindow && this.unsafeWindow.top && this.unsafeWindow.top.js && this.unsafeWindow.top.js.gmonkey && this.windowLoaded==false && !this.unsafeWindow.top.gtdinboxLoaded ){
				this.unsafeWindow.top.GTDCallBack = GIPROTOTYPE.bind(this, function(g){
					this._gmail = g;
					this.viewChange(g);
					
				});
				this.unsafeWindow.top.GTDInterceptEval = GIPROTOTYPE.bind(this, function(a){
					try{
						if( !((typeof a == "object") && (typeof a.length == "number")) ) return;
						a = a[0];
						this.dataChange(a);
					}catch(e){
						if( GTDDEBUGMODE ) this.unsafeWindow.console.log("GTDInterceptEval error\n" + e.toString());
					}
				});
					
				this.windowLoaded = true;
				this.unsafeWindow.top.gtdinboxLoaded = true;
				
				this.unsafeWindow.gtdinboxFrame = this._gtdFrame? true:false;
				var elScript = this.doc.createElement("SCRIPT");
				elScript.src = "chrome://gtdinbox/content/GTDInboxLocal.js";
				this.doc.getElementsByTagName("HEAD")[0].appendChild(elScript);
			}
			
			
			
		}catch(e){
			if( GTDDEBUGMODE ) alert("gtdinboxpage windowLoaded init\n" + e.toString());
		}
	});
	
	
	this.windowLoaded = false;
	this.window.addEventListener('load', onLoad, true);
	setTimeout(onLoad, 15000);	// act as a fail safe
	
}catch(e){
	if( GTDDEBUGMODE ) alert("gtdinboxpage constructor\n" + e.toString());
}
};

GTDInboxPage.prototype.init = function(){
try{
	if( !this._isInit ){			
			if( !this.unsafeWindow.console ){
				this.unsafeWindow.console = {log: function(){}, trace: function(){}};
			}
				
			if( !this._gmail || !this._gmail.getActiveViewElement ){
				if( GTDDEBUGMODE ) alert("gtdinboxPage GTDCallBack - could not find gmail");
				return;	// error
			}
			
			
			this.doc = this._gmail.getActiveViewElement().ownerDocument;
			GIPROTOTYPE._gtdinboxPage = this;
			
			this.gmailDOM = new GmailDOM(this);
			this.gmailDOM.viewChange(this._gmail);
			
			this.getSettings();
			this.install(true);
					
			
			this._isInit = true;
			if( this._gtdFrame ){	// Strip it of surrounding elements (its a popup)
				
				var el = this._gmail.getMastheadElement();
				el.style.display = "none";
				var el = this._gmail.getFooterElement();
				el.style.display = "none";
				var el = this._gmail.getNavPaneElement();
				el.style.display = "none";
				
				
				//if( !this.unsafeWindow.top._asyncFrames ) this.unsafeWindow.top._asyncFrames = {};
				//this.unsafeWindow.top._asyncFrames[gtdFrame] = true;
			}
			
			
			this._createAboutBox();
			
			var elNav = this.gmailDOM.element("NavPaneElement", this._gmail);
			this._asyncPopuper = new AsyncPopuper(this, elNav.ownerDocument.body);
			//this._contactFilterPopuper = new ContactFilterPopuper(this, elNav.ownerDocument.body);
			this._threadList = new ThreadList(this);
			GIPROTOTYPE.decodeEntities("0", this.doc);	// initialise it
			this.addCSS(this.gmailDOM.element("document", this._gmail));
			this.addCSS(this.doc);
			this._environment = new Environment(this, this.gmailDOM.element("MastheadElement", this._gmail));
			this._labels = new Labels(this);
				this._labels.addEventHandler( this, "refresh-labels", this._refreshLabels );
			this._labels.load(elNav);
			this._threadListUI = new ThreadListUI(this);
			this._threadListPopupUI = new ThreadListPopupUI(this, elNav.parentNode);
			this._composeUI = new ComposeUI(this);
			this._conversationUI = new ConversationUI(this);
			this._dashboard = new Dashboard(this);
			this._filterEnvironment = new FilterEnvironment(this);
			this._labelsUI = new LabelsUI(this);
			this._contactsUI = new ContactsUI(this);
			this._printButtonUI = new PrintButtonUI(this);
			
			this._lightbox = new Lightbox(this, this.doc.body);
			
			if( this.showMsg ){
				this._lightbox.setType( this.showMsg );
				this._lightbox.active(true);
				this.showMsg = null;	// ensure doesn't show again on reload
			}
			
			

	}
}catch(e){
	if( GTDDEBUGMODE ) alert("init\n" + e.toString());
}
};
GTDInboxPage.prototype.attachToBrowser = function(){
	this.browser = gBrowser.getBrowserForDocument( this.doc );
	this.browser.gtdinboxPage = this;
};
GTDInboxPage.prototype.addCSS = function(doc){
	var elLink = this.doc.createElement("LINK");
	elLink.type = "text/css";
	elLink.href = "chrome://gtdinbox/skin/gtdinbox.css";
	elLink.rel = "stylesheet";
	doc.getElementsByTagName("HEAD")[0].appendChild( elLink );
};

GTDInboxPage.prototype._createAboutBox = function(){
	this.elAbout = this._gmail.addNavModule("GTDInbox");
	
	var el = this.doc.createElement("DIV");
		el.className = "gtdinbox-about";
	this.elAbout.appendChild( el );
	
	// Create the warning box (hidden)
	this.elLabelsWarning = this.doc.createElement("DIV");
		this.elLabelsWarning.className = "labels-warning";
		this.elLabelsWarning.style.display = "none";
	el.appendChild( this.elLabelsWarning );
	var elWarningTitle = this.doc.createElement("DIV");
		elWarningTitle.className = "title";
		elWarningTitle.innerHTML = this.stringBundle.getString("Sidebar.About.Warning");
	this.elLabelsWarning.appendChild( elWarningTitle );
	var elWarningResolve = this.doc.createElement("DIV");
		elWarningResolve.className = "resolve";
		elWarningResolve.innerHTML = this.stringBundle.getString("Sidebar.About.Warning.Resolve");
	this.elLabelsWarning.appendChild( elWarningResolve );
	var elWarningDetail = this.doc.createElement("DIV");
		elWarningDetail.className = "detail";
		elWarningDetail.innerHTML = this.stringBundle.getString("Sidebar.About.Warning.Detail");
	this.elLabelsWarning.appendChild( elWarningDetail );
	
	var elOptions = this.doc.createElement("DIV");
		elOptions.className = "options";
	elOptions.innerHTML = this.stringBundle.getString("Sidebar.About.Options");	
	el.appendChild(elOptions);
	
	var elGettingStarted = this.doc.createElement("A");
		elGettingStarted.className = "options";
		elGettingStarted.href = "http://gtdinbox.com/support.htm";
		elGettingStarted.setAttribute("target", "_blank");
	elGettingStarted.innerHTML = this.stringBundle.getString("Sidebar.About.GettingStarted");	
	el.appendChild(elGettingStarted);
	
	var elDebug = this.doc.createElement("DIV");
		elDebug.className = "options";
		elDebug.style.display = "none";
	elDebug.innerHTML = this.stringBundle.getString("Sidebar.About.Debug");
	el.appendChild(elDebug);
	
	var elDonate = this.doc.createElement("DIV");
		elDonate.className = "donate";
	elDonate.innerHTML = "<a href='http://gtdinbox.com/donate.htm' target='_blank'><img src='https://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif' style='border:none' title=\"" + this.stringBundle.getString("Sidebar.About.Donate") + "\"/></a>";
	el.appendChild(elDonate);
	
	var elLogo = this.doc.createElement("A");
		elLogo.className = "pf-logo";
		elLogo.href = "http://productivefirefox.com";
		elLogo.setAttribute("target", "_blank");
		elLogo.innerHTML = "<img src=\"chrome://gtdinbox/content/pf-logo-small.png\" style='border:none'/>";
	el.appendChild( elLogo );
	
	
		
	//this.eventObservers.observe(elOptions, "mouseup", this._showOptions, false);
	elOptions.addEventListener("mousedown", GIPROTOTYPE.bind(this, function(){this._showLb('options')}), true);
	//elGettingStarted.addEventListener("mousedown", GIPROTOTYPE.bind(this, function(){this._showLb('gettingstarted')}), true);
	elDebug.addEventListener("mousedown", GIPROTOTYPE.bind(this, function(){this._showLb('debug')}), true);
	this.elLabelsWarning.addEventListener("mousedown", GIPROTOTYPE.bind(this, this._clickLabelsWarning), true);
};
GTDInboxPage.prototype._refreshLabels = function(){
	// Called after labels box refreshes
	// Test for presence of at least one default status label, if not found, show warning box
	
	var labelsHash = this._labels.getLabelsHash();
	var types = this.settings.labels.types;
	var found = false;
	for(d in types.Statuses.defaults){
		if( labelsHash[types.Statuses.prefix + types.Statuses.defaults[d]] ){
			found = true;
			break;
		}
	}
	this.elLabelsWarning.style.display = found? "none" : "";
};
GTDInboxPage.prototype._clickLabelsWarning = function(event){
	// Detect if clicked a link, if so, do something
try{
	var el = GIPROTOTYPE.element(event);
	
	if( GIPROTOTYPE.hasClassName(el, "warning.labels") ){
		var el = this.gmailDOM.element("edit-labels");
		if( el ) GIPROTOTYPE.doMouseEvent(this.gmailDOM.element("document"), el, "click");
	}else if( GIPROTOTYPE.hasClassName(el, "warning.options") ){
		this._showLb("options");
	};
}catch(e){
	if( GTDDEBUGMODE ) alert("gtdinboxpage _clickLabelsWarning\n" + e.toString());
}
};
GTDInboxPage.prototype._showLb = function(name){
try{
	if( !(typeof name=="string") ) return;
	this._lightbox.setType( name );
	this._lightbox.active(true);
}catch(e){
	if( GTDDEBUGMODE ) alert("gtdinboxpage _showOptions\n" + e.toString());
}
};


GTDInboxPage.prototype.view = function(name){
	name = name || "view";
	switch(name){
		case "gtdviewid":
			return this._viewid;
			break;
		case "view":
			return this._gmail.getActiveViewType();
			break;
	};
};

GTDInboxPage.prototype.viewChange = function(gmail){
try{
	if( !gmail ){
		if( GTDDEBUGMODE ) alert("gtdinboxpage viewChange\nCould not find gmail");
		return;
	}

	var viewType = gmail.getActiveViewType();
	this._gmail = gmail;
	
	if( !this._isInit ){
		if( viewType ){	// is loaded
			this.init();
		}else{	// not ready to load
			return;
		}
	}
	
	var elActive = gmail.getActiveViewElement();
	this._viewid = (new Date()).valueOf();
	elActive.setAttribute("gtdviewid", this._viewid);
	
	this.eventObservers.reset();
	this._labels.viewChange(gmail);
	this.gmailDOM.viewChange(gmail);
	
	switch(viewType){
		case "tl":	// threadlist
			this._threadListUI.viewChange( gmail );
			//this._printButtonUI.viewChange( gmail );
			break;
		case "cv":	// conversation
			this._conversationUI.viewChange(gmail);
			break;
		case "co":	// compose
			this._composeUI.viewChange(gmail);
			break;
		case "ct":	// contacts
			this._filterEnvironment.viewChange(gmail);
			this._contactsUI.viewChange(gmail);
			this._asyncPopuper.viewChange(gmail);
			break;
		case "s":	// settings
			this._labelsUI.viewChange(gmail);
			break;
	}
}catch(e){
	if( GTDDEBUGMODE ) alert("viewChange\n" + e.toString());
}
};

GTDInboxPage.prototype.dataChange = function(a){
	try{
		if( this._threadList ) this._threadList.parseAjaxResponse(a);
		if( this._environment ) this._environment.parseAjaxResponse(a);
		//this._labels.parseAjaxResponse(a);
		
		// Execute a Refresh when all data objects loaded for first time (only for Inbox; useful for auto label)
		if( this._threadList ){
			if( !this._firstFullLoad && this._threadList._threads.length>0 && this._threadList._threads.length==this._threadListUI.rowCount ){
				this._firstFullLoad = true;
				this._threadListUI.refresh(null, true);
			}
		}
	}catch(e){
		if( GTDDEBUGMODE ) alert("dataChange\n" + e.toString());
	}
};



GTDInboxPage.prototype.search = function(str){
		var elInput = this.gmailDOM.element("search-box");
	var elSubmit = this.gmailDOM.element("search-button");
	
	elInput.value = str;
	GIPROTOTYPE.doMouseEvent( this.doc, elSubmit, "click");
};


/* 
	SETTINGS
	Localised to each email account. Called on page load.
*/

GTDInboxPage.prototype.saveSettings = function(){
		
	var fullSettings = json.parse( this.gtdinboxBrowser.options.getOption("char", "gtdinbox.settings", "{}") );
	var email = this.gmailDOM.local("email-address") || "noEmail";
	fullSettings[email] = this.settings;
	
	var s = json.stringify( fullSettings );
	this.gtdinboxBrowser.options.setOption( "char", "gtdinbox.settings", s );
}
GTDInboxPage.prototype.getSettings = function(){
	this.settings = json.parse( this.gtdinboxBrowser.options.getOption("char", "gtdinbox.settings", "{}") );
	
	var email = this.gmailDOM.local("email-address") || "noEmail";
	if( !this.settings[email] ) this.settings[email] = {};
	this.settings = this.settings[email];	// pick the bit relevant to me
	
	
	var defaultSettings = this.createDefaultSettings();
	
	GIPROTOTYPE.extend(this.settings, defaultSettings);
	this.saveSettings();
	
};
GTDInboxPage.prototype.createDefaultSettings = function(){
	var defaultSettings = {};	// defaults
	defaultSettings.labels = {};
	defaultSettings.labels.types = {};
	defaultSettings.labels.types["Statuses"] = {prefix: "S/", defaults: {NextAction:'Next Action', Action:'Action', WaitingOn:'Waiting On', SomeDay:'Some Day', Finished:'Finished'}};
	defaultSettings.labels.types["Projects"] = {prefix: "P/"};
	defaultSettings.labels.types["Contexts"] = {prefix: "C/"};
	defaultSettings.labels.types["References"] = {prefix: "R/"};
	defaultSettings.labels.types["Old"] = {name:"Old Items", prefix: "Old/"};
	defaultSettings.labels.types["Misc"] = {prefix: ""};
	defaultSettings.labels.starForNextAction = false;
	defaultSettings.labels.onlyOneStatus = true;
	defaultSettings.async = {};
	defaultSettings.async.popupNewTab = false;
	defaultSettings.showHiders = {};
	defaultSettings.showHiders.rememberOpenClose = true;
	defaultSettings.showLabelTreeNodes = {};
	defaultSettings.showLabelTreeNodes.rememberOpenClose = true;
	return defaultSettings;
};
GTDInboxPage.prototype.install = function(reset){
try{
	var lastVersion = this.settings.lastVersion || 0;
	
	if( !reset && lastVersion==1.98 ) return;
	if( reset ) lastVersion = 0;
	
		
	if( lastVersion < 1.90 ){
		this.showMsg = "welcome";
		if( this.gtdinboxBrowser.options.getOption("char", "Gtd.InstallOptionsComplete") ){	// install before
			this.showMsg = "update";
		}
		
		this.gtdinboxBrowser.options.setOption("char", "gtdinbox.debugMode", "1");
	
		this.db.execute("DROP TABLE IF EXISTS project_label_activity");
		this.db.execute("CREATE TABLE project_label_activity (label VARCHAR(50) NOT NULL, thread VARCHAR(20) NOT NULL, contact VARCHAR(100) NOT NULL, date INTEGER)");
	
		this.createTable("auto_labelled", false, "label VARCHAR(255), msgid VARCHAR(25) NOT NULL", ["msgid, account"]);
		
		this.createTable("thread_labels", false, "thread VARCHAR(25), label VARCHAR(255)", null, ["thread, label"]);
		this.createTable("thread_contacts", false, "thread VARCHAR(25), contact VARCHAR(150), type INTEGER", null, ["thread, contact"]);	// type is 0: sender, 1: recipient	
			
		lastVersion = 1.90;
	}
	if( lastVersion < 1.93 ){
		this.createTable("contact_emails", false, "contact_name VARCHAR(150), contact_email VARCHAR(150)", null, ["contact_name, contact_email"]);
			
		lastVersion = 1.93;
	}
	if( lastVersion < 1.94 ){
		this.settings.labels.starForNextAction = true;
		this.settings.labels.onlyOneStatus = true;
		this.settings.labels.types.Statuses.defaults.Finished = "Finished";
		
		var fAddLabel = GIPROTOTYPE.bind(this, function(){
			if( !this._labels.hasLabel( this.settings.labels.types.Statuses.prefix + "Finished" ) ){
				var finalCallback = GIPROTOTYPE.bind(this, function(){
					var el = this.gmailDOM.element("inbox-link");
					GIPROTOTYPE.doMouseEvent(this.doc, el, "click");	// refresh
				});
				this.gmailDOM.addLabel( this.settings.labels.types.Statuses.prefix + "Finished", null, finalCallback);
			}
		});
		setTimeout(fAddLabel, 4000);
		
		lastVersion = 1.94;
	}
	if( lastVersion < 1.98 ){
		this.createTable("recent_news_items", false, "url VARCHAR(255)");
		this.settings.showLabelTreeNodes = {};
		this.settings.showLabelTreeNodes.rememberOpenClose = true;
		
		lastVersion = 1.98;
	}
		
	// Finally, record our update:
	this.gtdinboxBrowser.options.setOption("char", "gtdinbox.lastVersion", lastVersion);
	
	this.settings.lastVersion = lastVersion;
	this.saveSettings();
	
}catch(e){
	if( GTDDEBUGMODE ) alert("GtdinboxBrowser install\n" + e.toString());
}
};
GTDInboxPage.prototype.createTable = function(name, useId, fields, indices, uniqueIndices){
	if( useId ) fields = "id INTEGER PRIMARY KEY AUTOINCREMENT, " + fields;
	fields += ", account VARCHAR(100), date INTEGER, session INTEGER, session_modified INTEGER";	// session/date used for server syncing; when it comes (upload, make sure both sessions are set. if update, set session_modified to null; and issue 'update' command when sent to server). 
	
	this.db.execute("DROP TABLE IF EXISTS " + name);
	this.db.execute("CREATE TABLE " + name + " (" + fields + ")");
	var ic = 0;
	if( indices ){
		for( var i = 0; i < indices.length; i++ ){
			this.db.execute("CREATE INDEX " + name + "_idx" + ic++ + " ON " + name + "(" + indices[i] + ")");
		}
	}
	if( uniqueIndices ){
		for( var i = 0; i < uniqueIndices.length; i++ ){
			this.db.execute("CREATE UNIQUE INDEX " + name + "_idx" + ic++ + " ON " + name + "(" + uniqueIndices[i] + ")");
		}
	}
};




GTDInboxPage.prototype.unload = function(){
	// Clear up variables
	try{
	
	if( !this.doc && !this.browser ) return;

	if( this._threadList ) this._threadList.destroy();
	if( this._labels ) this._labels.destroy();
	if( this._threadListUI ) this._threadListUI.destroy();
	this.eventObservers.destroy();
	if( this._asyncPopuper ) this._asyncPopuper.destroy();
	if( this._contactFilterPopuper ) this._contactFilterPopuper.destroy();
	if( this._filterEnvironment ) this._filterEnvironment.destroy();
	if( this._environment ) this._environment.destroy();
	if( this._composeUI ) this._composeUI.destroy();
	if( this._conversationUI ) this._conversationUI.destroy();
	if( this._lightbox ) this._lightbox.destroy();
	if( this._dashboard ) this._dashboard.destroy();

	this.browser.gtdinboxPage = null;
	delete this.browser.gtdinboxPage;
	
	this.unsafeWindow = null;
	this.gtdinboxBrowser = null;
	this.window = null;
	this.tab = null;
	this.browser = null;
	this.doc = null;

	}catch(e){if( GTDDEBUGMODE ) alert("gtdinboxPage unload\n" + e.toString())}
};

